﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DienLib.PopUp
{
    /// <summary>
    /// Delegate Callback pass into CountDownForm
    /// </summary>
    /// <param name="sender">CountDownForm</param>
    /// <returns>TRUE will Stop Count Down, FALSE will continue Count Down</returns>
    public delegate bool StopCountToCheck(object sender);

    /// <summary>
    /// Interaction logic for PopUpCountDown.xaml
    /// </summary>
    public partial class CountDownWPF : UserControl
    {
        private int _TimeOutSec;
        private int _CountDownSec;
        private bool _IsCounting;
        private bool _IsPolling;
        private StopCountToCheck _Callback;
        private object _RetObj = null;
        private string _Comment;
        DispatcherTimer timer1;

        private CountDownWPF(int sec, string title, string comment, StopCountToCheck callback)
        {
            InitializeComponent();
            timer1 = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, new EventHandler(timer1_Tick), this.Dispatcher);
            _TimeOutSec = _CountDownSec = sec;
            _IsCounting = true; _IsPolling = true;
            _Callback = callback;
            _Comment = comment;

            Run run = new Run(textBlock1.Text); run.Foreground = Brushes.Black; textBlock1.Inlines.Clear(); textBlock1.Inlines.Add(new Bold(run));
            textBlock2.Inlines.Clear(); textBlock3.Inlines.Clear();

            textBlock1.Inlines.AddRange(Command.HighlightTextBlockMatch(title, "\"[^\"]*\"", null, true)); // "[^"]*" : Mean "*" any character with double-quotes
            textBlock2.Inlines.AddRange(Command.HighlightTextBlockMatch(comment, "\"[^\"]*\"", System.Windows.Media.Brushes.Blue, true));
            textBlock3.Inlines.Add(new Run("Will time out in : "));
            textBlock3.Inlines.Add(new Bold(new Run(_CountDownSec.ToString())));
            textBlock3.Inlines.Add(new Run(" seconds"));


            //timer1.Start();
        }

        /// <summary>
        /// Additional Method from User to Get Value back from PopUp
        /// </summary>
        /// <param name="timeOut">TimeOut in Second</param>
        /// <param name="callback">Callback to check Condition every second</param>
        /// <param name="comment">Your Comment</param>
        /// <param name="title">Waiting : WHAT ?</param>
        /// <returns>PopUp Return Value after TimedOut or click Cancel or Condition from Callback Match</returns>
        public static object ShowDialog(int timeOut, string comment, string title = "N/A", StopCountToCheck callback = null)
        {
            CountDownWPF popup = new CountDownWPF(timeOut, title, comment, callback);
            Window window = new Window();
            window.Content = popup;
            window.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
            window.WindowStyle = System.Windows.WindowStyle.None;
            window.AllowsTransparency = true;
            window.Background = System.Windows.Media.Brushes.Transparent;
            window.Topmost = true;
            window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            window.MouseLeftButtonDown += Window_MouseLeftButtonDown;
            System.Media.SystemSounds.Asterisk.Play();

            //Block here & Wait
            window.ShowDialog();

            window.MouseLeftButtonDown -= Window_MouseLeftButtonDown;
            popup.timer1.Stop();
            popup.timer1.Tick -= popup.timer1_Tick;
            return popup._RetObj;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //if (_Callback(this, out _RetObj))
            if (_Callback != null)
                if (_Callback(this))
                { // Check Method Condition every 1 sec if _Callback not Null
                    try { Window.GetWindow(this).Close(); }
                    catch (Exception ex) { throw new InvalidOperationException("Cannot close Parent not Window : " + ex.Message); }
                }

            if (!_IsCounting) return; // If stop counting then return, just check _Method Condition only

            if (_CountDownSec > 0) // Else Check CountDown
            {
                _CountDownSec--;
                textBlock3.Inlines.Clear();
                textBlock3.Inlines.Add(new Run("Will time out in : "));
                textBlock3.Inlines.Add(new Bold(new Run(_CountDownSec.ToString())));
                textBlock3.Inlines.Add(new Run(" seconds"));
                return;
            }
            // Timed Out
            _IsCounting = false;
            button1.IsEnabled = true; // Enable Continue Wait
            textBlock3.Text = "Already Timed Out !";
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {   // Click Continue Wait
            button1.IsEnabled = false;
            _CountDownSec = _TimeOutSec;
            _IsCounting = true;
            textBlock3.Inlines.Clear();
            textBlock3.Inlines.Add(new Run("Will time out in : "));
            textBlock3.Inlines.Add(new Bold(new Run(_CountDownSec.ToString())));
            textBlock3.Inlines.Add(new Run(" seconds"));
            //timer1.Start();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {   // Click Cancel
            try { Window.GetWindow(this).Close(); }
            catch (Exception ex) { throw new InvalidOperationException("Cannot close Parent not Window : " + ex.Message); }
        }

        private static void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            (sender as System.Windows.Window).DragMove();
        }
    }
}
